package checker;


import checker.utils.ConvertUtil;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * 参数校验工具
 *
 * @author alan
 * @date 2022/7/4 15:05
 */
public class Checker<T> {

    private List<Condition> conditions = new ArrayList<>();

    /**
     * 判断该值不能为传入值
     */
    public Checker<T> ne(SFunction<T, ?> column, Object val, String desc) {
        conditions.add(new Condition(getFieldMeta(column), ECheckType.NE, val, desc));
        return this;
    }

    /**
     * 判断值不能为空
     */
    public Checker<T> notNull(SFunction<T, ?> column, String desc) {
        conditions.add(new Condition(getFieldMeta(column), ECheckType.NOTNULL, null, desc));
        return this;
    }

    /**
     * 不能为空且不能为传入值
     */
    public Checker<T> notNe(SFunction<T, ?> column, Object val, String desc) {
        conditions.add(new Condition(getFieldMeta(column), ECheckType.NOTNULL_NE, val, desc));
        return this;
    }

    /**
     * 不能为空且不能为传入值
     */
    public Checker<T> in(SFunction<T, ?> column, Collection<Object> val, String desc) {
        conditions.add(new Condition(getFieldMeta(column), ECheckType.IN, val, desc));
        return this;
    }

    public Checker<T> diy(SFunction<T, ?> column, String desc, ExtendFuction<T> checkFunction) {
        conditions.add(new Condition(getFieldMeta(column), ECheckType.EXTEND, null, desc, checkFunction));
        return this;
    }

    /**
     * 执行校验逻辑
     */
    public List<String> check(T obj) {

        List<String> res = new ArrayList<>();
        if (Objects.isNull(obj)) {
            res.add("参数为空");
            return res;
        }
        Class<?> targetClass = obj.getClass();
        for (Condition condition : conditions) {
            ECheckType type = condition.getType();
            try {
                Field field = targetClass.getDeclaredField(condition.getField());
                field.setAccessible(true);
                Object result = field.get(obj);
                switch (type) {
                    case NE:
                        if (Objects.equals(result, condition.getVal())) {
                            res.add(condition.getDesc());
                            break;

                        }
                    case NOTNULL:
                        if (Objects.isNull(result)) {
                            res.add(condition.getDesc());
                            break;
                        }
                        break;
                    case NOTNULL_NE:
                        if (Objects.isNull(result) || result.equals(condition.getVal())) {
                            res.add(condition.getDesc());
                            break;
                        }
                    case IN:
                        Object val = condition.getVal();
                        if (val instanceof Collection) {
                            Collection temp = (Collection) val;
                            if (Objects.isNull(result) || !temp.contains(result)) {
                                res.add(condition.getDesc());
                            }
                        }
                        break;
                    case EXTEND:
                        ExtendFuction extendFunction = condition.getExtendFunction();
                        if (extendFunction.check(result)) {
                            res.add(condition.getDesc());
                        }
                        break;
                    default:
                }
            } catch (Exception e) {
                res.add(String.format("字段(%s)不存在", condition.getField()));
            }
        }
        return res;

    }

    private String getFieldMeta(SFunction<T, ?> column) {
        return ConvertUtil.convertToFieldName(column);
    }

}
